package cjj;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.*;

@WebServlet("/admin/forgotPassword")
public class AdminForgotPasswordServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        String username = request.getParameter("username");
        String oldPassword = request.getParameter("oldPassword");
        String newPassword = request.getParameter("newPassword");

        // 验证输入
        if (username == null || username.isEmpty() ||
                oldPassword == null || oldPassword.isEmpty() ||
                newPassword == null || newPassword.isEmpty()) {
            request.setAttribute("errorMessage", "请填写所有字段");
            request.getRequestDispatcher("/cjj/admin_forgot_password.jsp").forward(request, response);
            return;
        }

        // 打印操作信息（用于调试）
        System.out.println("密码重置尝试 - 用户名: " + username);

        Connection conn = null;
        try {
            // 获取数据库连接
            conn = getDatabaseConnection();

            // 第一步：查询管理员信息
            String querySql = "SELECT * FROM admin WHERE username = ?";
            try (PreparedStatement queryStmt = conn.prepareStatement(querySql)) {
                queryStmt.setString(1, username);
                ResultSet rs = queryStmt.executeQuery();

                if (rs.next()) {
                    Integer adminId = rs.getInt("id");
                    String storedPassword = rs.getString("password");

                    // 验证原密码
                    if (storedPassword.equals(hashPassword(oldPassword))) {
                        // 第二步：更新密码
                        String updateSql = "UPDATE admin SET password = ? WHERE id = ?";
                        try (PreparedStatement updateStmt = conn.prepareStatement(updateSql)) {
                            updateStmt.setString(1, hashPassword(newPassword));
                            updateStmt.setInt(2, adminId);
                            int rowsAffected = updateStmt.executeUpdate();

                            if (rowsAffected > 0) {
                                // 密码更新成功
                                System.out.println("密码重置成功 - 管理员ID: " + adminId);
                                request.setAttribute("successMessage", "密码修改成功，请使用新密码登录");
                                request.getRequestDispatcher("/cjj/admin_forgot_password.jsp").forward(request, response);
                            } else {
                                // 更新失败
                                System.err.println("密码更新失败，未影响任何行");
                                request.setAttribute("errorMessage", "密码修改失败，请重试");
                                request.getRequestDispatcher("/cjj/admin_forgot_password.jsp").forward(request, response);
                            }
                        }
                    } else {
                        // 原密码错误
                        System.out.println("密码重置失败 - 原密码错误");
                        request.setAttribute("errorMessage", "原密码错误");
                        request.getRequestDispatcher("/cjj/admin_forgot_password.jsp").forward(request, response);
                    }
                } else {
                    // 管理员账号不存在
                    System.out.println("密码重置失败 - 管理员账号不存在");
                    request.setAttribute("errorMessage", "管理员账号不存在");
                    request.getRequestDispatcher("/cjj/admin_forgot_password.jsp").forward(request, response);
                }
            }
        } catch (SQLException e) {
            // 处理数据库异常
            System.err.println("密码重置数据库操作错误: " + e.getMessage());
            System.err.println("SQL状态码: " + e.getSQLState());
            System.err.println("错误代码: " + e.getErrorCode());
            e.printStackTrace();

            // 根据不同的SQL状态码提供更具体的错误信息
            String errorMessage = "数据库错误";
            if (e.getSQLState() != null) {
                switch (e.getSQLState()) {
                    case "42S02": // 表不存在
                        errorMessage = "数据库表结构错误，请检查admin表是否存在";
                        break;
                    case "28000": // 权限错误
                        errorMessage = "数据库访问权限不足，请检查用户权限";
                        break;
                    case "08001": // 连接拒绝
                        errorMessage = "无法连接到数据库服务器，请检查数据库是否运行";
                        break;
                    default:
                        errorMessage = "数据库操作失败: " + e.getMessage();
                }
            }

            request.setAttribute("errorMessage", errorMessage);
            request.getRequestDispatcher("/cjj/admin_forgot_password.jsp").forward(request, response);
        } catch (Exception e) {
            // 捕获其他异常
            System.err.println("密码重置过程中发生错误: " + e.getMessage());
            e.printStackTrace();
            request.setAttribute("errorMessage", "系统错误: " + e.getMessage());
            request.getRequestDispatcher("/cjj/admin_forgot_password.jsp").forward(request, response);
        } finally {
            // 确保关闭连接
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 获取数据库连接
    private Connection getDatabaseConnection() throws SQLException {
        try {
            // 加载驱动类
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("MySQL JDBC驱动加载成功");

            // 构建连接URL，添加更详细的参数
            String url = "jdbc:mysql://localhost:3306/mysql-0" +
                    "?useSSL=false" +
                    "&serverTimezone=UTC" +
                    "&allowPublicKeyRetrieval=true" +
                    "&useUnicode=true" +
                    "&characterEncoding=UTF-8";

            // 获取连接
            Connection conn = DriverManager.getConnection(url, "root", "root");
            System.out.println("成功连接到数据库");
            return conn;
        } catch (ClassNotFoundException e) {
            System.err.println("找不到MySQL JDBC驱动类，请检查依赖");
            e.printStackTrace();
            throw new SQLException("数据库驱动加载失败", e);
        } catch (SQLException e) {
            System.err.println("数据库连接失败: " + e.getMessage());
            System.err.println("SQL状态码: " + e.getSQLState());
            System.err.println("错误代码: " + e.getErrorCode());
            e.printStackTrace();
            throw e;
        }
    }

    // 密码哈希方法
    private String hashPassword(String password) {
        try {
            // 创建SHA-256哈希实例
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hashBytes = md.digest(password.getBytes("UTF-8"));

            // 将字节数组转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = String.format("%02x", b);
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException | java.io.UnsupportedEncodingException e) {
            throw new RuntimeException("密码哈希失败", e);
        }
    }
}